Примеры реализации программ
Задание 1. Тип эксперимента: пакет.
Размер пакета: 32-512 байт.
Тайм-аут: 5 мс.
Вид соединения: дейтаграмма.
Размер передаваемых данных: 8 Кбайт.
Вывод статистики на сервере. Необходимо построить гистограмму, отображающую зависимость времени передачи от размера пакета.
Листинг программы. Реализация на языке C#
Модуль «Клиент»
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Fonns;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace SIT
{ public partial class Fonnl : Form
{
private int localPort; 11 локальный порт
private int remotePort; // удаленный порт
private int timeOut; II тайм-аут
private long size_data; 11 размер передаваемых данных
IPAddress remotelPAddres; // удаленный IP- адрес public int[] sizes = II массив размеров отправляемых пакетов
new int[] { 32, 64, 128, 256, 512 };
public int s = 0; II переменная для вывода на экран размера отправленного пакета
private delegate void InvokeDelegate(); // делегат, для вывода информации
private AutoResetEvent autoEvent = new AutoResetEvent(false); // события для синхронизации потоков
private AutoResetEvent autoEvent2 = new AutoResetEvent(false);
void PrintLabelStart()
{
label2.Text = "подключение";
}
void PrintLabelConnect()
{
label2.Text = "подключено";
}
void PrintConnectionO
{
richTextBoxl.Text += DateTime.Now + " Подключение к серверуп";
}
void PrintConnectionEnd()
{
richTextBoxl.Text += DateTime.Now + " Соединение установленноп";
richTextBoxl.SelectionStart = richTextBoxl.Text.Length; richTextBox 1 .ScrollToCaret();
}
void PrintRequest()
{
richTextBoxl.Text += DateTime.Now + " Отправлен запросп"; richTextBoxl. Selections tart = richTextBoxl.Text.Length; richTextBox 1 .ScrollToCaret();
}
void PrintPackedO
{
richTextBoxl.Text += DateTime.Now + " Отправлен пакет размером " + s + " байтп";
richTextBoxl. Selections tart = richTextBoxl.Text.Length; richTextBox 1 .ScrollToCaret();
}
void PrintAnsver()
{
richTextBoxl.Text += DateTime.Now + " Получен ответп"; richTextBoxl. Selections tart = richTextBoxl.Text.Length; richTextBox 1 .ScrollToCaret();
}
void PrintEnd()
{
richTextBoxl.Text += DateTime.Now + " Отправка данных завер-
шенап";
richTextBoxl. Selections tart = richTextBoxl.Text.Length; richTextBox 1 .ScrollToCaret();
}
void EnableButtonO
{
button2.Enabled = true;
}
private void Recive()
{
try
{
UdpClient Recive = new UdpClient(localPort);
IPEndPoint reciver = null;
Red ve.Recei ve(ref rec i ver);
Recive.Close();
autoEvent.SetO;
}
catch(Exception ex)
{
MessageBox.Show(ex.ToStringO);
}
}
private void ReciveData()
{
try
{
UdpClient Recive = new UdpClient(localPort);
IPEndPoint reciver = null; while (true)
{
Reci ve.Recei ve(ref reciver); autoEvent2.Set();
}
}
catch(Exception ex)
{
MessageBox.Show(ex.ToStringO);
}
}
private void Request()
{
try
{
label2.BeginInvoke(new InvokeDelegate(PrintLabelStart)); richTextBox 1 .BeginInvoke(new InvokeDelegate(PrintConnection));
UdpClient Send = new UdpClient();
IPEndPoint sender = new IPEndPoint(remoteIPAddres, remotePort);
Thread tRec = new Thread (Red ve); tRec.IsBackground = true; tRec.Start();
string welcome = localPort.ToStringO + + textBox4.Text;
byte[] data = Encoding.UTF8.GetBytes(welcome);
while (true)
{
Send.Send(data, data.Length, sender);
richTextBoxl.BeginInvoke(new InvokeDelegate(PrintRequest)); if (autoEvent.WaitOne(lOOO) = true)
{
richTextBox 1 .BeginInvoke(new InvokeDele- gate(PrintAnsver));
break;
}
}
Send.Close();
label2.BeginInvoke(new InvokeDelegate(PrintLabelConnect)); richTextBox 1 .BeginInvoke(new InvokeDele- gate (Pri ntConnectionEnd));
button2.BeginInvoke(new InvokeDelegate(EnableButton));
}
catch(Exception ex)
{
MessageBox.Show(ex.ToStringO);
}
}
private void SendData()
{
try
{
UdpClient Send = new UdpClient();
IPEndPoint sender = new IPEndPoint(remoteIPAddres, remotePort);
int index = 0; s = sizes[index]; long tempSize = 0;
Thread tRec2 = new Thread(ReciveData); tRec2.IsBackground = true; tRec2.Start(); while (true)
{
byte[] Data = new byte[sizes[index]];
Send.Send(Data, Data.Length, sender);
richTextBoxl.BeginInvoke(new InvokeDelegate(PrintPacked)); if (autoEvent2.WaitOne(timeOut) = true)
{
tempSize += sizes[index]; richTextBox 1 .BeginInvoke(new InvokeDele- gate(Pri ntAnsver));
autoEvent2 .Reset();
Thread.Sleep(50);
}
if (tempSize = size_data)
{
if (index < (sizes.Length - 1))
{
index++; s = sizes [index]; tempSize = 0;
}
else
break;
tempSize = 0;
}
}
byte[] data = Encoding.UTF8.GetBytes("end"); Send.Send(data, data.Length, sender);
Send.CloseO;
richTextBox 1 .BeginInvoke(new InvokeDelegate(PrintEnd));
}
catch(Exception ex)
{
MessageBox.Show(ex.ToStringO);
}
}
public Forml()
{
In i ti al i zeComponent(); try {
// Получение имени компьютера.
String host = System.Net.Dns.GetHostNameO;
// Получение ip-адреса.
System.Net.IPAddress ip = Sys- tem.Net.Dns.GetHostByName(host).AddressList[0]; this.textBox4.Text = ip.ToStringO;
}
catch(Exception ex)
{
MessageBox.Show(ex.ToStringO);
}
}
private void button l_Click(object sender, EventArgs e)
{
try
{
localPort = int.Parse(textBoxl.Text); remotePort = int.Parse(textBox2.Text); timeOut = int.Parse(textBox5.Text);
remotelPAddres = IPAddress.Parse(textBox3.Text); size_data = int.Parse(textBox6.Text);
Thread tRec = new Thread(Request); tRec.IsBackground = true; tRec.Start();
}
catch(Exception ex)
{
MessageBox.Show(ex.ToStringO);
}
}
private void button2_Click(object sender, EventArgs e)
{
try
{
Thread tRec = new Thread(SendData); tRec.IsBackground = true; tRec.Start();
}
catch(Exception ex)
{
MessageBox.Show(ex.ToStringO);
}
}
}
}
Модуль «Сервер»
using System;
using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Diagnostics;
namespace SIT2
{
public partial class Forml : Form
{
private int localPort; // локальный порт
private int remotePort; // удаленный порт
IPAddress remotelPAddres; // удаленный IP-адрес int size; // размер принятого пакета
private AutoResetEvent autoEvent = new AutoResetEvent(false); private delegate void InvokeDelegate(); // делегат, для вывода информации
private int[] sizes = // массив размеров отправляемых пакетов
new int[] { 32, 64, 128, 256, 512 };
private double[] times = new double[]{0, 0, 0, 0, 0}; // массив времен private Stopwatch sWatch = new Stopwatch(); // таймер
void PrintConnectClientO
{
richTextBoxl.Text += DateTime.Now + " Подключен клиент - " + remotelPAddres.ToStringO + " ";
richTextBoxl. Selections tart = richTextBoxl.Text.Length; richTextBox 1 .ScrollToCaret();
}
void PrintData()
{
richTextBoxl.Text += DateTime.Now + " Получен пакет данных размером " + size + " байтп";
richTextBox l.SelectionStart = richTextBoxl.Text.Length;
richTextBox 1 .ScrollToCaret();
}
void PrintEnd()
{
richTextBox 1.Text += DateTime.Now + " Передача данных завершена^";
richTextBox l.SelectionStart = richTextBox l.Text.Length; richTextBox 1 .ScrollToCaret();
}
void PrintChartO
{
chartl.Series["Seriesl"].Points.DataBindXY(sizes, times);
}
public Forml()
{
InitializeComponentO;
try
{
// Получение имени компьютера.
String host = System.Net.Dns.GetHostName();
// Получение ip-адреса.
System.Net.IPAddress ip = System.Net.Dns.GetHostByName(host). AddressList[0];
this.textBox2.Text = ip.ToStringO;
}
catch(Exception ex)
{
MessageBox.Show(ex.ToStringO);
}
}
void Connect()
{
try
{
UdpClient receivingUdpClient = new UdpClient(localPort);
IPEndPoint RemotelpEndPoint = null;
byte[] data = receivingUdpClient.Receive(ref RemotelpEndPoint);
string infoClient = Encoding.UTF8.GetString(data); string port = ip = bool flag = false;
for (int i = 0; i < infoClient.Length; ++i)
{
if (infoClient[i] == '*')
{
flag = true; continue;
}
if (!flag)
port += infoClient[i]; else
ip += infoClient [i];
}
remotePort = int.Parse(port); remotelPAddres = IPAddress.Parse(ip);
UdpClient send = new UdpClient();
IPEndPoint sendering = new IPEndPoint(remoteIPAddres, remote-
Port);
byte[] datagram = new byte[8]; send.Send(datagram, datagram.Length, sendering);
receivingUdpClient.Close();
send.Close();
autoEvent.Set();
richTextBox 1 .BeginInvoke(new InvokeDelegate (PrintConnectClient));
}
catch(Exception ex)
{
MessageBox.Show(ex.ToStringO);
}
}
void RecivingO
{
try
{
autoEvent.WaitOne();
UdpClient receivingUdpClient = new UdpClient(localPort); IPEndPoint RemotelpEndPoint = null;
UdpClient send = new UdpClient();
IPEndPoint sendering = new IPEndPoint(remoteIPAddres, remote-
Port);
while (true)
{
sWatch.StartO;
byte[] data = receivingUdpClient.Receive(ref RemotelpEndPoint);
sWatch.StopO;
string tempEnd = Encoding.UTF8.GetString(data); if (tempEnd == "end") break; size = data.Length;
richTextBoxl.BeginInvoke(new InvokeDelegate(PrintData)); byte[] datagram = new byte[8]; send.Send(datagram, datagram.Length, sendering);
switch (data.Length)
{
case 32:
times[0] += (double)sWatch.ElapsedMilliseconds / 1000; break; case 64:
times[l] += (double)sWatch.ElapsedMilliseconds / 1000; break;
case 128:
times[2] += (double)sWatch.ElapsedMilliseconds / 1000; break; case 256:
times[3] += (double)sWatch.ElapsedMilliseconds / 1000; break; case 512:
times[4] += (double)sWatch.ElapsedMilliseconds / 1000; break;
};
sWatch.Reset();
}
receivingUdpClient.Close();
send.Close();
richTextBox 1 .BeginInvoke(new InvokeDelegate(PrintEnd)); chartl .BeginInvoke(new InvokeDelegate(PrintChart));
}
catch(Exception ex)
{
MessageBox.Show(ex.ToStringO);
}
}
private void button l_Click(object sender, EventArgs e)
{
richTextBox 1.Text += DateTime.Now + " Ожидается подключение клиентап";
try
{
localPort = int.Parse(textBoxl.Text);
Thread tRecQ = new Thread(Connect); tRecQ.IsBackground = true; tRecQ. Start();
Thread tRecR = new Thread(Reciving); tRecR.IsBackground = true;
tRecR.Start();
}
catch(Exception ex)
{
MessageBox.Show(ex.ToStringO);
}
}
}
}
Клиент
Сервер
Задание 2. Объем передаваемых данных. 16 Кбайт. Вид соединения: Дейтаграмма.
Таймаут: 15 мс.
Листинг программы. Реализация на языке C++
#include
#pragma hdrstop #include
#include
#include "Unitl.h"
#pragma package(smart_init)
#pragma resource TfMain *fMain;
TFileStream *inpFile, *outFile;
LANA_ENUM lan_number;
NCB neb;
intWorkingLana=2, nSessions=20, nNames=30, Time0ut=15, count=0, NBNAMENUM=0; int s=0;
char NameString[]="IOmeHT", PriemString[]="CepBep"; float size=0;
int VOLUMES []={ 8, 16, 32, 64, 128, 256, 512}; double TIMES[]={0,0,0,0,0,0,0};
intVolum=8;
intdeltaX=30;
#deflne B_S 512 #define TotalSize 24576 void Priem();
_fastcallTfMain::TfMain(TComponent* Owner)
: TForm(Owner)
{
} boolNbReset(byte 1)
{
memset(&ncb,0,sizeof(ncb)); ncb.ncb_command=NCBRESET; ncb.ncb_lana_num=l; ncb.ncb_callname[0]=nSessions; neb. ncb_cal lname [2]=nN ames; if(Netbios(&ncb)!=NRC_GOODRET)
{
fMain->Memo->Lines->Add("Reset NCB Error. RetCode: Ox"+IntToStr(ncb.ncb_retcode)); return 0;
}
else return 1;
} void PaintStatistic()
{
int Max=TIMES[0];
for (int r=l; r<7; r++) if(TIMES[r]>Max) Max=TIMES[r]; int y; int x=0;
fMain->Im->Canvas->Brush->Color=clWhite;
fMain->Im->Canvas->Rectangle(0,0,fMain->Im->Width,fMain->Im-
>Height);
for (int r=0; r<7; r++)
{
if (Max != 0) у = fMain->Im->Height - fMain->Im- >Height*TIMES[r]/(Max* 1.5); else у = 0;
fMain->Im->Canvas->Brush->Color=clBlue;
fMain->Im->Canvas->Rectangle(x,y,(x+deltaX),lMain->Im->Height);
fMain->Im->Canvas->Brush->Color=clWhite;
fMain->Im->Canvas->TextOutA(x+3,y-30,IntToStr(VOLUMES[r])+" байт"); fMain->Im->Canvas->TextOutA(x+3,y-15,FloatToStr(TIMES[r])+" сек"); x+=deltaX;
}
}
void_fastcallTfMain::btFileClick(TObject ^Sender)
{
if (OpenDialog->Execute())
{
edFile->Text=OpenDialog->FileName; inpFile = new TFileStream(edFile->Text, fmOpenRead); s=inpFile->Size;
lbFileSize->Caption = IntToStr(s) + " байт";
bt4->Enabled = true;
}
}
void_fastcallTfMain::FormClose(TObject *Sender, TCloseAction&Action)
{
delete inpFile;
}
void_fastcallTfMain::rbOtprClick(TObject ^Sender)
{
edFile->Enabled=l; btFile->Enabled= 1; lbFileSize->Enabled= 1; btRecv->Visible = 0; bt4->Visible = 1;
1ЬЫате->СарЬоп="Имя: Клиент";
}
void_fastcallTfMain::rbPolClick(TObject ^Sender)
{
edFile->Enabled=0; btFi le->Enabled=0; lbFi leS i ze->Enabled=0; bt4->Visible = 0; btRecv->Visible = 1; lbName->Caption="HMH: Сервер";
}
void_fastcallTfMain::btLANAClick(TObject *Sender)
{
Memo->Lines->Add("-----------------------------------------");
if (NbReset(WorkingLana))
{
memset(&ncb,0,sizeof(ncb));
ncb.ncb_command=NCBENUM;
ncb.ncb_buffer=(unsigned char*)&lan_number; ncb.ncb_length=sizeof(lan_number); if(Netbios(&ncb)==NRC_GOODRET)
{
Memo->Lines->Add("LANA Number List:"); for(inti=0; i
["?+IntToS tr(lan_nu mber.lana[i ])+"]");
Memo->Lines->Add("-----------------------------------------");
}
else
{
Memo->Lines->Add("LANA NCB Error. RetCode:
Ox"+IntToS tr(ncb .ncb_re tcode));
}
}
btGetLANA->Enabled= 1; edGetLANA->Enabled=l;
}
void_fastcallTfMain::btRecvClick(TObject *Sender)
{
Priem();
}
char Buffer[B_S]={0}; clock_t Begin=clock(); double Tim=0;
void Priem()
{
if(NbReset(WorkingLana))
{
TimeOut=S trT oInt(fMai n->edTi meOUT->Text); memset(&ncb,0,sizeof(ncb));
ncb.ncb_command=NCBADDNAME;
neb. ncb_lana_num=W orkingLana;
ncb.ncb_rto = TimeOut;
memset(ncb.ncb_name, 0, NCBNAMSZ);
memcpy(ncb.ncb_name, PriemString, lstrlen(PriemString));
fMain->Refresh();
NBNAMENUM=ncb.ncb_num;
if(Netbios(&ncb)==NRC_GOODRET)
{
count=0; while (1)
{
fMain->Refresh();
char Buffer[B_S]={0};
Buffer[B_S]=NULL;
count++;
memset(&neb,0,sizeof(ncb)); ncb.ncb_command=NCBDGREC V; neb. ncb_lana_num=W orkingLana; neb. ncb_num=0xFF; ncb.ncb_buffer=(PUCHAR)Buffer; neb. ncb_length=Vol um;
if(Netbios(&ncb)==NRC_GOODRET)
{
if ( Buffer[l ]=='-' && Buffer[2]=='~' && Buffer[3]=='')
{
fMain->Memo->Lines->Add("Coo6uieHHe было получено"); fMain->Memo->Lines->Add(" "); goto Exit;
}
if ( Buffer[l]=='~' && Buffer[2]==' ’ && Buffer[3]==' ’)
{
Уо1ит*=2;
count=0;
fMain->Memo->Lines->Add("Next: "+IntToStr(Volum)+" байт"); fMain->Memo->Lines->Add(" ");
}
else
{
fMain->Memo->Lines->Add('TIojiy4eHo"); fMain->Memo->Lines->Add(IntToStr(count)+": "+Buffer); fMain->Memo->Lines->Add(" ");
}
}
В uffer[B_S ]=NULL;
} 11 while } I I if Netbios else {
fMain->Memo->Lines->Add("ADDNAME NCB Error. RetCode: Ox"+IntToStr(ncb.ncb_retcode));
fMain->Memo->Lines->Add("-----------------------------------------");
}
} 11 if Reset Exit:
}
inti=0;
//---------------------------------------------------------------------------
void_fastcallTfMain::bt4Click(TObject ^Sender)
{
intSendData=0;
Volum = VOLUMES [i];
lbV->Caption="Packet: "+IntToStr(Volum)+" byte(s)"; fMain->Refresh(); char Buffer[B_S]={ 0}; if (NbReset(WorkingLana))
{
TimeOut=S trToIn t(edTimeOUT->Tex t);
memset(&ncb,0,sizeof(ncb));
ncb.ncb_command=NCBADDNAME;
neb. ncb_lana_n um=W orkingLana; ncb.ncb_rto = TimeOut;
memcpy(&ncb.ncb_name,NameString,lstrlen(NameString));
fMain->Refresh();
ncb.ncb_buffer=(PUCHAR)Buffer;
neb. ncb_length=Vol um;
memcpy(&ncb.ncb_callname,PriemString,lstrlen(PriemString));
Netbios(&ncb);
NBNAMENUM=ncb.ncb_num;
count=0;
Begin=clock();
while(l){
char Buffer[B_S]={0}; count++;
if (count>(s/Volum))
{
if (Volum == B_S)
{
Buffer[B_S]=NULL;
Buffer[ 1 Buffer[2]='~';
Buffer[3]='
neb. ncb_command=NCBDGSEND; ncb.ncb_buffer=(PUCHAR)Buffer; ncb.ncb_length=Volum;//sizeof(Buffer);
Netbios(&ncb);
Memo->Lines->Add("Coo6meHne6bmooToenaHO "); Memo->Lines->Add(" ");
TIMES [i]=Tim;
deltaX=(fMain->Im->Width)/7;
PaintStatistic();
break;
}
else
{
Buffer[B_S]=NULL;
Buffer [1 Buffer[2]=' ’;
Buffer[3]=
ncb.ncb_command=NCBDGSEND;
ncb.ncb_buffer=(PUCHAR)Buffer;
ncb.ncb_length=Volum;
Netbios(&ncb);
Memo->Lines->Add("Next: "+IntToStr(Volum*2)+" byte(s)"); Memo->Lines->Add(" ");
TIMES [i]=Tim; break;
}
}
else
{
Buffer[B_S]=NULL;
inpFile->Seek(Volum*(count-l), soFromBeginning); inpFile->Read(Buffer, Volum);
Memo->Lines->Add(IntToStr(count)+":"+ Buffer); Memo->Lines->Add(" "); neb. ncb_command=NCBDGSEND; ncb.ncb_buffer=(PUCHAR)Buffer; neb. ncb_length=Vol um;
Netbios(&ncb);
SendData+=Volum;
}
Tim=((clock()-Begin)/CLK_TCK);
fMain->Refresh();
} // while(l)
}
else
{
Memo->Lines->Add("OmH6Kanepe;aa4H" );
Memo->Lines->Add(" ");
}
i++;
if (i< 7) fMain->bt4Click(fMain); else {
lbV->Caption="Packet:"; i = 0;
}
}
void_fastcallTfMain::FormCreate(TObject ^Sender)
{
Im->Canvas->Brush->Color=clWhite; Im->Canvas->Rectangle(0,0,Im->Width,Im->Height); rbPol->Checked = 1;
}
void_fastcallTfMain::btGetLANAClick(TObject ^Sender)
{
WorkingLana=StrToInt(edGetLANA->Text);
}
Сервер
Задание 3. Тип эксперемента: time out.
Размер пакета 512 байт.
TimeOut в диапозоне от 15 до 25 мс.
Вид соединения: логический канал.
Размер данных: 32 кбайта.
Вывод статистики: на клиенте.
Листинг программы. Реализация на языке Kotlin с использованием GUUavaFX
ClientMain.kt
import j avafx .appl icati on. Appl ication import javafx.fxml.FXMLLoader import javafx.scene.Parent import javafx.scene.Scene import javafx.stage.Stage class ClientMain : Application() {
@Throws(Exception: :class) ovenide fun start(primaryStage: Stage) { System.setPropertyC'prism.lcdtext", "false") val root = FXMLLoad-
er.load
}
companion object {
@JvmStatic
fun main(args: Array
}
}
}
sample.fxml
filelnput. channel .position(O)
println("Данные с задержкой $delay мс между пакетами отправлены")
}
output. write("exit".toByteArray())
output.flushO
button. isDisable = false
while (lisEnd) {
}
} catch (e: Exception) { e.pri ntStackT race() button. isDisable = false }
}
fun bytesToLong(bytes: ByteArray): Long { val buffer = ByteBuffer.allocate(java.lang.Long.BYTES) buffer.put(bytes) buffer.flipO return buffer, long }
}
}
ServerMain.kt
i mport javafx .appli cati on. Appl i cation import javafx.fxml.FXMLLoader import javafx.scene.Parent import javafx.scene.Scene import javafx.stage.Stage import java.io.BufferedReader import java.io.IOException import java.io.InputStreamReader import java.io.PrintWriter import java.net.ServerSocket import java.net.Socket
/**
- * Created by medium on 31.05.17.
- */
class ServerMain: Application() { override fun start(primaryStage: Stage) { System.setPropertyO'prism.lcdtext", "false") val root = FXMLLoader.load
primaryStage.title = "Server" primaryStage.scene = Scene(root, 800.0, 400.0) primaryStage.show()
}
companion object {
@JvmStatic
fun main(args: Array
}
}
}
main.fxml
cTextArea fx:id="logArea" editable="false" prefHeight="325.0" pref- Width="800.0" wrapText="true" BorderPane.alignment="CENTER" />
ServerController.kt
import javafx.beans.value.ChangeListener import javafx.fxml.FXML import j avafx. scene .control. В u tton
import javafx .scene.control .Label
import javafx.scene.control.TextArea
import java.net.Networklnterface
import java.net.ServerSocket
import java.net.Socket
import java.util.regex.Pattern
import javafx.beans.value.ObservableValue
import java.io.*
import java.nio.ByteBuffer
- * Created by medium on 31.05.17.
- */
class ServerController {
private val SOCKET_NUMBER = 9999
private val PACKET_SIZE = 512
@FXML
lateinit var refreshButton: Button @FXML
lateinit var rebootButton: Button @FXML
lateinit var currentlpLabel: Label @FXML
lateinit var logArea: TextArea val threadRunnable: Runnable = Runnable { logArea.appendText("CepBep запущенп") var out: OutputStream? = null var servers: ServerSocket? = null var fromclient: Socket? = null javafx.application.Platform.runLater { rebootButton.isDisable = true rebootButton.text = "Сервер запущен"
}
try {
servers = ServerSocket(SOCKET_NUMBER) } catch (e: IOException) { logArea.appendTextCНевозможно прослушать порт " + SOCKET_NUMBER + "п")
}
try {
log Area.appendText( "Ожидание подключения клиента. An") fromclient = servers! !.accept()
logArea.appendText( "Клиент " + fromclient.inetAddress.hostAddress + подключилсяп")
} catch (e: IOException) {
logArea.appendText("HeB03MO>KHO подключить клиентап")
}
var "in4 = fromclient! !.getInputStream()
var buffer = ByteArray(PACKET_SIZE)
out = fromclient.getOutputStreamO
var now = System.currentTimeMillis()
var input = 'in'.read(buffer)
now = System.cunentTimeMillisO - now
var totalTime = OL
var time = now
val output: String
var past: String? = null
while ((input) != null) {
var str = String(buffer)
if (str.contains("exit")ll past == str) {
break
} else if (str.contains("Onext")) { out.write(longToBytes(time - now)) out.flushO
println("Данные обработаны за ${time - now} мс") str = " Данные обработаны за ${time - now} мспп" totalTime+=time time = 0 } else {
out.write(longToBytes(-2L))
out.flushO
// println("Пакет обработан за $now мс") str += 'ЛпПакет обработан за $now мсп"
}
javafx.application.Platform.runLater { logArea.appendText(str)
}
past = str
now = System.currentTimeMillis() input = 'in'.read(buffer) now = System.cuiTentTimeMillis() - now time += now }
out.write(longToBytes(-lL))
out.flushO
javafx.application.Platfomi.runLater { rebootButton.isDi sable = false rebootButton.text = "Перезапустить сервер"
}
out.closeO
vin'.close()
fromclient.closeO
servers?.close()
javafx.application.Platfomi.runLater {
logArea.appendText("06utee время обработки пакетов StotalTime
мсп")
}
}
fun initializeO {
currentlpLabel.text = "Текущий IP адрес: " + getCurrentIp() refreshButton.setOnAction {
currentlpLabel.text = "Текущий IP адрес: " + getCurrentlpO
}
logArea.textPropertyO.addListener { observable, oldValue, newValue -> logArea.scrollTop = java.lang.Double.MAX_VALUE //this will scroll to the bottom
//use Double.MIN_VALUE to scroll to the top
}
rebootButton.setOnAction { logArea.text ="" startReceive()
}
startReceive()
}
private fun staitReceive(){
Thread(threadRunnable).stai1()
}
private fun getCurrentIp(): String {
val networklnterfaces = Networklnterface.getNetworklnterfacesO
while (networklnterfaces.hasMoreElementsO) {
val networklnterface = networkInterfaces.nextElement()
val addresses = networklnterface.inetAddresses
while (addresses.hasMoreElements()) {
val address = addresses.nextElement()
if (address.hostAddress != "I27.0.l.l"&& address.hostAddress != "127.0.0.1"
&& isIpAddress(address.hostAddress)) { return address.hostAddress }
}
}
return "Устройство не подключено"
}
fun isIpAddress(address: String): Boolean {
val pattern = Pattem.compile("A(([0-9]l[l-9][0-9]ll[0-9]{2}l2[0-4][0- 9] I25 [0-5]).) {3} ([0-9] I [ l-9] [0-9] 11 [0-9] {2} I2 [0-4] [0-9] I25 [0-5])$") return pattem.matcher(address).matches()
}
fun longToBytes(x: Long): ByteArray { val buffer = ByteBuffer.allocate(java.lang.Long.BYTES) buffer.putLong(x) return buffer.arrayO }
fun bytesToLong(bytes: ByteArray): Long { val buffer = ByteBuffer.allocate(java.lang.Long.BYTES) buffer.put(bytes) buffer.flipO return buffer.long }
Пожелании программистам
Чтобы освоить программирование приложений на выше рассмотренных протоколах, необходимо иметь опыт программирования не меньше 1 года, а чтобы правильно уметь ими пользоваться - как минимум 2-3 года. Для начинающих программистов достаточно изучить основные типы библиотеки VCL (хотя некоторые классы в ней не продуманны и не согласованы). Функциональность и замудренность сетевых классов оставляет желать лучшего, а полезны только классы TIdTCPServer, TIdClient, TIdUDPServer и TldUDPClient. Все остальные сетевые классы нужны, наверное, только самим разработчикам этой библиотеки.
Внимание!!! При сдаче лабораторных работ ЗАПРЕЩЕНО использовать библиотеку нестандартных типов AltemativeTypes, так как она содержит сетевые классы с автоматическим управлением каналами и протоколами, а значит, нет смысла изучать устройство сокетов. Разрешается только ознакомиться со всеми возможностями этих сетевых протоколов и изучить их свойства. Также запрещено использование в частных и коммерческих целях без уведомления автора.
В данном пособии рассмотрено 30 % материала по управлению этими протоколами, другие 30 % вы узнаете из лабораторных, а 40 % информации вы уже должны знать, иначе нет смысла даже пытаться программировать с нуля.
САМОЕ ГЛАВНОЕ для программиста - это красивый почерк в его программном коде.
Для решения задач, связанных с написанием программ для организации обмена данными с сети с использованием сетевых протоколов, в качестве эффективного инструментального средства можно воспользоваться модулем Alternative Types Library.